Added [dev-dependencies] sections to Cargo.toml
authorYehuda Katz + Carl Lerche <engineering@tilde.io>
Wed, 2 Jul 2014 23:58:25 +0000 (16:58 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 3 Jul 2014 14:30:11 +0000 (07:30 -0700)
If you put a dependency in [dev-dependencies], it will only be
used when building (or testing) your packages, not other packages that
depend on it.

src/cargo/util/toml.rs
tests/test_cargo_compile_path_deps.rs

index e220a60d5ba4ea9c2c1c58fff6a74241d7b1d842..391fd11b0326cd552e574b1e14745203a28434f8 100644 (file)
@@ -111,6 +111,7 @@ pub struct TomlManifest {
     lib: Option<Vec<TomlLibTarget>>,
     bin: Option<Vec<TomlBinTarget>>,
     dependencies: Option<HashMap<String, TomlDependency>>,
+    dev_dependencies: Option<HashMap<String, TomlDependency>>
 }
 
 #[deriving(Decodable,Encodable,PartialEq,Clone,Show)]
@@ -128,6 +129,13 @@ impl TomlProject {
     }
 }
 
+struct Context<'a> {
+    deps: &'a mut Vec<Dependency>,
+    source_id: &'a SourceId,
+    source_ids: &'a mut Vec<SourceId>,
+    nested_paths: &'a mut Vec<Path>
+}
+
 impl TomlManifest {
     pub fn to_manifest(&self, source_id: &SourceId)
         -> CargoResult<(Manifest, Vec<Path>)>
@@ -145,47 +153,18 @@ impl TomlManifest {
 
         let mut deps = Vec::new();
 
-        // Collect the deps
-        match self.dependencies {
-            Some(ref dependencies) => {
-                for (n, v) in dependencies.iter() {
-                    let (version, source_id) = match *v {
-                        SimpleDep(ref string) => {
-                            (Some(string.clone()), SourceId::for_central())
-                        },
-                        DetailedDep(ref details) => {
-                            let reference = details.branch.clone()
-                                .or_else(|| details.tag.clone())
-                                .or_else(|| details.rev.clone())
-                                .unwrap_or_else(|| "master".to_str());
-
-                            let new_source_id = match details.git {
-                                Some(ref git) => {
-                                    let kind = GitKind(reference.clone());
-                                    let loc = try!(Location::parse(git.as_slice()));
-                                    let source_id = SourceId::new(kind, loc);
-                                    // TODO: Don't do this for path
-                                    sources.push(source_id.clone());
-                                    Some(source_id)
-                                }
-                                None => {
-                                    details.path.as_ref().map(|path| {
-                                        nested_paths.push(Path::new(path.as_slice()));
-                                        source_id.clone()
-                                    })
-                                }
-                            }.unwrap_or(SourceId::for_central());
-
-                            (details.version.clone(), new_source_id)
-                        }
-                    };
-
-                    deps.push(try!(Dependency::parse(n.as_slice(),
-                                                     version.as_ref().map(|v| v.as_slice()),
-                                                     &source_id)))
-                }
-            }
-            None => ()
+        {
+
+            let mut cx = Context {
+                deps: &mut deps,
+                source_id: source_id,
+                source_ids: &mut sources,
+                nested_paths: &mut nested_paths
+            };
+
+            // Collect the deps
+            try!(process_dependencies(&mut cx, self.dependencies.as_ref()));
+            try!(process_dependencies(&mut cx, self.dev_dependencies.as_ref()));
         }
 
         let project = self.project.as_ref().or_else(|| self.package.as_ref());
@@ -205,6 +184,54 @@ impl TomlManifest {
     }
 }
 
+fn process_dependencies<'a>(cx: &mut Context<'a>,
+                            new_deps: Option<&HashMap<String, TomlDependency>>)
+                            -> CargoResult<()> {
+    match new_deps {
+        Some(ref dependencies) => {
+            for (n, v) in dependencies.iter() {
+                let (version, source_id) = match *v {
+                    SimpleDep(ref string) => {
+                        (Some(string.clone()), SourceId::for_central())
+                    },
+                    DetailedDep(ref details) => {
+                        let reference = details.branch.clone()
+                            .or_else(|| details.tag.clone())
+                            .or_else(|| details.rev.clone())
+                            .unwrap_or_else(|| "master".to_str());
+
+                        let new_source_id = match details.git {
+                            Some(ref git) => {
+                                let kind = GitKind(reference.clone());
+                                let loc = try!(Location::parse(git.as_slice()));
+                                let source_id = SourceId::new(kind, loc);
+                                // TODO: Don't do this for path
+                                cx.source_ids.push(source_id.clone());
+                                Some(source_id)
+                            }
+                            None => {
+                                details.path.as_ref().map(|path| {
+                                    cx.nested_paths.push(Path::new(path.as_slice()));
+                                    cx.source_id.clone()
+                                })
+                            }
+                        }.unwrap_or(SourceId::for_central());
+
+                        (details.version.clone(), new_source_id)
+                    }
+                };
+
+                cx.deps.push(try!(Dependency::parse(n.as_slice(),
+                                                 version.as_ref().map(|v| v.as_slice()),
+                                                 &source_id)))
+            }
+        }
+        None => ()
+    }
+
+    Ok(())
+}
+
 #[deriving(Decodable,Encodable,PartialEq,Clone,Show)]
 struct TomlTarget {
     name: String,
index 7b4406eb9dbea687ea8c52b1856d6b2209bba5a7..16cde69b3d1f9f02658a451704fe4e824b068ec2 100644 (file)
@@ -70,9 +70,13 @@ test!(cargo_compile_with_nested_deps_shorthand {
             }
         "#);
 
-    p.cargo_process("cargo-build")
-        .exec_with_output()
-        .assert();
+    assert_that(p.cargo_process("cargo-build"),
+        execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                     {} bar v0.5.0 (file:{})\n\
+                                     {} foo v0.5.0 (file:{})\n",
+                                    COMPILING, p.root().display(),
+                                    COMPILING, p.root().display(),
+                                    COMPILING, p.root().display())));
 
     assert_that(&p.bin("foo"), existing_file());
 
@@ -81,6 +85,77 @@ test!(cargo_compile_with_nested_deps_shorthand {
       execs().with_stdout("test passed\n"));
 })
 
+test!(cargo_compile_with_dev_deps {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+
+            name = "foo"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [dependencies.bar]
+
+            version = "0.5.0"
+            path = "bar"
+
+            [[bin]]
+
+            name = "foo"
+        "#)
+        .file("src/foo.rs",
+              main_file(r#""{}", bar::gimme()"#, ["bar"]).as_slice())
+        .file("bar/Cargo.toml", r#"
+            [project]
+
+            name = "bar"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [dev-dependencies.baz]
+
+            version = "0.5.0"
+            path = "baz"
+
+            [[lib]]
+
+            name = "bar"
+        "#)
+        .file("bar/src/bar.rs", r#"
+            pub fn gimme() -> &'static str {
+                "zoidberg"
+            }
+        "#)
+        .file("bar/baz/Cargo.toml", r#"
+            [project]
+
+            name = "baz"
+            version = "0.5.0"
+            authors = ["wycats@example.com"]
+
+            [[lib]]
+
+            name = "baz"
+        "#)
+        .file("bar/baz/src/baz.rs", r#"
+            pub fn gimme() -> &'static str {
+                "nope"
+            }
+        "#);
+
+    assert_that(p.cargo_process("cargo-build"),
+        execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                                     {} foo v0.5.0 (file:{})\n",
+                                    COMPILING, p.root().display(),
+                                    COMPILING, p.root().display())));
+
+    assert_that(&p.bin("foo"), existing_file());
+
+    assert_that(
+      cargo::util::process(p.bin("foo")),
+      execs().with_stdout("zoidberg\n"));
+})
+
 test!(no_rebuild_dependency {
     let mut p = project("foo");
     let bar = p.root().join("bar");